package me.pinion.controller;


import me.pinion.Log;
import me.pinion.check.annotation.AllowMethod;
import me.pinion.check.annotation.AllowRole;
import me.pinion.check.annotation.CheckRunTime;
import me.pinion.controller.annotation.RouteBind;
import me.pinion.exception.BookExistException;
import me.pinion.kit.CommonKit;
import me.pinion.model.*;
import me.pinion.model.book.Book;
import me.pinion.service.AttachService;
import me.pinion.service.BookService;
import me.pinion.service.CommentService;
import me.pinion.service.TagService;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

@RouteBind("/book")
public class BookController extends Controller{

    private int PAGE_SIZE = 10;

    CommentService commentService;
    BookService bookService;
    TagService tagService;
    AttachService attachService;

    @CheckRunTime
    public void index(){
        if (getParaToInt(0) != null){
            this._detail(getParaToInt(0));
            return;
        }
        setAttr("books", bookService.popularBooks(1, PAGE_SIZE));
        render("/book/index.ftl");
    }

    private boolean _detail(int id){
        Book book = Book.dao.findById(id);
        setAttr("book", book);
        render("/book/book_detail.ftl");
        return true;
    }

    public void explorer() throws UnsupportedEncodingException {
        String tag = getPara("tag") != null? CommonKit.urlVal2utf8(getPara("tag")):null;
        if (tag != null && tag.equals("")){
            tag = null;
        }
        setAttr("curTag", Tag.dao.findByName(tag));
        setAttr("recent", getPara("recent"));
        setAttr("tags", tagService.popularTags(Book.class));
        setAttr("books", bookService.popularBooks(Tag.dao.findByName(tag), getPara("recent"), 1, PAGE_SIZE));
        render("/book/book_explorer.ftl");
    }

    public void preview() {
        int id = getParaToInt(0, 0);
        Book book = Book.dao.findById(id);
        this.setAttr("book", book);
        render("/book/book_preview_page.ftl");
    }

    public void search_html() throws UnsupportedEncodingException {
        String keyword = CommonKit.urlVal2utf8(getPara("q"));
        List<Book> books = bookService.search(keyword);
        this.setAttr("books", books);
        render("/book/book_list.ftl");
    }

    public void searchForAutoComplete() throws UnsupportedEncodingException {
        String keyword = CommonKit.urlVal2utf8(getPara("q"));
        renderJson(bookService.searchBookName(keyword));
    }

    public void add(){
        render("/book/book_add.ftl");
    }

    @AllowRole({"USER"})
    public void create(){
        if (getRequest().getMethod().equals("POST")){
            String bookname = getPara("bookname");
            String description = getPara("description");
            String pseudonym = getPara("pseudonym");

            Book book = new Book();
            book.set("cover", getPara("cover"));
            book.set("bookname", bookname);
            book.set("pseudonym", pseudonym);
            book.set("description", description);
            book.set("author_id", this.<User>getSessionAttr("user").getLong("id"));
            book.save();

            if(getParaValues("tag[]") != null){
                for (String tag:getParaValues("tag[]")){
                    Tag.dao.findByName(tag).put(book);
                }
            }

            redirect("/book/" + book.getInt("id"));
        }else {
            render("/book/book_create.ftl");
        }
    }

    public void edit(){
        Book book = Book.dao.findById(getParaToInt(0));
        if (getRequest().getMethod().equals("POST")){
            String bookname = getPara("bookname");
            String description = getPara("description");
            String pseudonym = getPara("pseudonym");
            book.set("cover", getPara("cover"));
            book.set("bookname", bookname);
            book.set("pseudonym", pseudonym);
            book.set("description", description);
            book.update();
            if(getParaValues("tag[]") != null){
                for (String tag:getParaValues("tag[]")){
                    Tag.dao.findByName(tag).put(book);
                }
            }
            redirect("/book/" + book.getInt("id"));
        }else {
            setAttr("book", book);
            render("/book/book_edit.ftl");
        }
    }

    @AllowMethod({"POST"})
    public void delete(){

    }

    @AllowRole("USER")
    public void uploadText() throws IOException, BookExistException {
        if (getRequest().getMethod() == "POST"){
            Attach attach = attachService.saveAttach(this, "txt");
            Book book =  bookService.loadFile(attach.getFile(), curUser(), "UTF-8");
        }
        render("/book/upload_text.ftl");
    }

    @AllowRole({"USER"})
    public void my(){
        String type = getPara(0);
        String template = "/freemarker/account/center_book.ftl";
//                "/book/book_list.ftl";
        if (type == null) {
            type = "my";
            template = "/freemarker/account/center_book.ftl";
        }

        try {
            Method method =  BookService.class.getDeclaredMethod(type, User.class);
            List<Book> books = (List<Book>) method.invoke(bookService, curUser());
            setAttr("books", books);
            render(template);
        } catch (NoSuchMethodException e) {
            Log.e(e);
        } catch (InvocationTargetException e) {
            Log.e(e);
        } catch (IllegalAccessException e) {
            Log.e(e);
        }
    }
}
